#include "NetworkDelegate.h"

#include "Network.h"

#include "cocos2d.h"

using namespace RakNet;
using namespace std;

CServerHelper *CServerHelper::s_pServerHelper = NULL;

CServerHelper *CServerHelper::GetInstance()
{
    if(NULL == s_pServerHelper)
    {
        s_pServerHelper = new CServerHelper;
    }
    
    return s_pServerHelper;
}

//---------------------------------------------------------------------------------------------------------------------------/
void CServerHelper::ConnectServer()
{
    DisconnetAll();
    m_pAccountServer = CAccountServer::GetInstance();
	m_pAccountServer->Connect("192.168.2.191");
}

//---------------------------------------------------------------------------------------------------------------------------/
void CServerHelper::DisconnetAll()
{
    if(NULL != m_pAccountServer)
    {
        m_pAccountServer->ReleaseConnect();
    }
    
    if(NULL != m_pGameServer)
    {
        m_pGameServer->ReleaseConnect();
    }
}

//---------------------------------------------------------------------------------------------------------------------------/
void CServerHelper::UserLogin(const char *szName , const char *szPsw)
{
    if(NULL == m_pAccountServer)
    {
        return;
    }
	BitStream bsSend;
	char sname[32] = {0};
    
	strcpy(sname, szName);
    
	char spsw[32] = {0};
	strcpy(spsw, szPsw);
    
    cocos2d::CCLog("%s, %s", sname, spsw);
    
	bsSend.Reset();
	bsSend.Write((MessageID)ID_GAME_ACCOUNT);
    
	bsSend.Write((MessageID)ID_ACCOUNTINDEX_LOGIN);
	bsSend.Write(sname,32);
	bsSend.Write(spsw, 32);
	m_pAccountServer->SendPacketToServer(bsSend);
}

//---------------------------------------------------------------------------------------------------------------------------/
void CServerHelper::UserRegister(const char *szName , const char *szPsw, std::string strEmail)
{
    if(NULL == m_pAccountServer)
    {
        return;
    }
	char sname[32];
    
	strcpy(sname, szName);
    
	char spsw[32];
	strcpy(spsw, szPsw);
	BitStream bsSend;
	bsSend.Write((RakNet::MessageID)ID_GAME_ACCOUNT);
	bsSend.Write((RakNet::MessageID)ID_ACCOUNTINDEX_REGISTER);
	bsSend.Write(sname,32);
	bsSend.Write(spsw,32);
	bsSend.Write(strEmail.c_str(),32);
	m_pAccountServer->SendPacketToServer(bsSend);
}

//---------------------------------------------------------------------------------------------------------------------------/
bool CServerHelper::ChooseRegion(int id)
{
    if(NULL == m_pAccountServer)
    {
        return false;
    }
    BitStream bsSend;
    bsSend.Write((RakNet::MessageID)ID_GAME_ACCOUNT);
    bsSend.Write((RakNet::MessageID)ID_ACCOUNTINDEX_SELECT);
    bsSend.Write(id);
    
    return m_pAccountServer->SendPacketToServer(bsSend);
}

//---------------------------------------------------------------------------------------------------------------------------/
bool CServerHelper::ConnectRegion()
{
    if(!m_regionUser._bGetData)
    {
        return false;
    }
    m_pGameServer = CGameServer::GetInstance();
    m_pGameServer->Connect(m_regionUser._serverAddr);
    
    return true;
}

//---------------------------------------------------------------------------------------------------------------------------/
bool CServerHelper::LoginRegion()
{
    if(NULL == m_pGameServer)
    {
        return false;
    }
    
    BitStream bsSend;
    bsSend.Write((RakNet::MessageID)ID_GAME_LOGING);
    bsSend.Write((RakNet::MessageID)ID_LOGING_LOGING);
    bsSend.Write(m_regionUser._szName, 32);
    bsSend.Write(m_regionUser._psw);
    
    return m_pGameServer->SendPacketToServer(bsSend);
}

//---------------------------------------------------------------------------------------------------------------------------/
bool CServerHelper::CreateRole(const RoleInfo &info)
{
    if(NULL == m_pGameServer)
    {
        return false;
    }
    
    BitStream bsSend;
    bsSend.Write((RakNet::MessageID)ID_GAME_LOGING);
    bsSend.Write((RakNet::MessageID)ID_LOGING_CREATENAME);
    bsSend.Write(info._szName, 32);
    bsSend.Write(info._id);
    
    return m_pGameServer->SendPacketToServer(bsSend);
}

//---------------------------------------------------------------------------------------------------------------------------/
bool CServerHelper::CreateRoom()
{
    
    if(NULL == m_pGameServer)
    {
        return false;
    }
    BitStream bsSend;
    bsSend.Write((RakNet::MessageID)ID_GAME_ROOMING);
    bsSend.Write((RakNet::MessageID)ID_ROOM_RANDOM);
    
    return m_pGameServer->SendPacketToServer(bsSend);
     
}

//---------------------------------------------------------------------------------------------------------------------------/
bool CServerHelper::SendFightMove(const Move &moveInfo)
{
     if(NULL == m_pGameServer)
     {
         return false;
     }
     BitStream bsSend;
     bsSend.Write((RakNet::MessageID)ID_GAME_ROOMING);
     bsSend.Write((RakNet::MessageID)ID_ROOM_FIGHT);
     bsSend.Write((RakNet::MessageID)ID_FIGHT_MOVE);
     bsSend.Write((char *)&moveInfo, sizeof(moveInfo));
     
     return m_pGameServer->SendPacketToServer(bsSend);
}

//---------------------------------------------------------------------------------------------------------------------------/
bool CServerHelper::SendFightAttack(const AttactSend &attackInfo)
{
    if(NULL == m_pGameServer)
    {
        return false;
    }
    BitStream bsSend;
    bsSend.Write((RakNet::MessageID)ID_GAME_ROOMING);
    bsSend.Write((RakNet::MessageID)ID_ROOM_FIGHT);
    bsSend.Write((RakNet::MessageID)ID_FIGHT_ATTACT);
    bsSend.Write((char *)&attackInfo, sizeof(attackInfo));
    
    return m_pGameServer->SendPacketToServer(bsSend);
}

//---------------------------------------------------------------------------------------------------------------------------/
bool CServerHelper::SendRoomChat(const char *szRoom, int len)
{

	if(NULL == m_pGameServer)
	{
		return false;
	}

	BitStream bsSend;
	bsSend.Write((RakNet::MessageID)ID_GAME_ROOMING);
	bsSend.Write((RakNet::MessageID)ID_ROOM_MESSAGE);
	bsSend.Write(len);
	bsSend.Write(szRoom, len);

	return m_pGameServer->SendPacketToServer(bsSend);
}

bool CServerHelper::SendChatToName(const char *szName, const char *szMsg, int msgLen)
{
	if(NULL == m_pGameServer)
	{
		return false;
	}

	char name[32] = {0};
	strcpy(name, szName);
	BitStream bsSend;
	bsSend.Reset();
	bsSend.Write((RakNet::MessageID)ID_GAME_LOGING);
	bsSend.Write((RakNet::MessageID)ID_LOGING_MESSAGE);
	bsSend.Write(name, 32);
	bsSend.Write(msgLen);
	bsSend.Write(szMsg, msgLen);

	return m_pGameServer->SendPacketToServer(bsSend);
}
//---------------------------------------------------------------------------------------------------------------------------/
void CServerHelper::ReceivePacket()
{
    if(NULL != m_pAccountServer)
    {
        _ReceiveAccountPacket();
    }
    
    if(NULL != m_pGameServer)
    {
        _ReceiveGamePacket();
    }
	
}

//---------------------------------------------------------------------------------------------------------------------------/
void CServerHelper::_ReceiveAccountPacket()
{

    if(NULL == m_pAccountDelegate)
    {
        return;
    }
    
    Packet *pPacket = m_pAccountServer->GetTopPacket(); 
    
	if(NULL == pPacket)
	{
		return;
	}
    
	switch (pPacket->data[0])
	{
        case ID_CONNECTION_REQUEST_ACCEPTED:
		{
			// 连接成功
			m_pAccountDelegate->connectServerBack(true);
		}
            break;
            
        case ID_GAME_ACCOUNT:
		{
			switch(pPacket->data[1])
			{
                case ID_ACCOUNTINDEX_REGISTER_SUCCESS:
				{
					// 注册成功
					m_pAccountDelegate->userRegisterBack(true);
				}
                    break;
                    
                case ID_ACCOUNTINDEX_REGISTER_ERROR:
                {
                    m_pAccountDelegate->userRegisterBack(false);
                }
                    break;
                    
                case ID_ACCOUNTINDEX_LOGIN_SUCCESS:
				{
					// 获取服务器选区信息
                    
					RakNet::BitStream bsReceive(pPacket->data, pPacket->length, false);
					bsReceive.IgnoreBytes(2);
                    
                    vector<RegionInfo> vRegions;
					while(true)
					{
						RegionInfo info;
						
						if(!bsReceive.Read(info._id))
						{
							break;
						}
                        
						if(!bsReceive.Read(info._userCount))
						{
							break;
						}
                        
						if(!bsReceive.Read(info._szName, 32))
						{
                    
							break;
						}
                        
						vRegions.push_back(info);
					}
                    
                    // 登陆成功
                    m_pAccountDelegate->userLoginBack(true, &vRegions);
				}
                    break;
                    
                case ID_ACCOUNTINDEX_LOGIN_ERROR:
				{
					// 登陆失败 密码错误
					m_pAccountDelegate->userLoginBack(false, NULL);
				}
                    break;
                    
                case ID_ACCOUNTINDEX_SELECT_SUCCESS:
				{
                    // 返回选区结果,保存服务器发来的账号密码用于登陆
                    
                    RakNet::BitStream bsReceive(pPacket->data, pPacket->length, false);
					bsReceive.IgnoreBytes(2);
                    memset(m_regionUser._szName, 0, 32);
                    bsReceive.Read(m_regionUser._szName,32);  
                    bsReceive.Read(m_regionUser._serverAddr,32);
                    bsReceive.Read(m_regionUser._psw);
                    
                    m_regionUser._bGetData = true;
					m_pAccountDelegate->chooseRegionBack(true, &m_regionUser);
				}
                    break;
                    
                case ID_ACCOUNTINDEX_SELECT_ERROR:
                {
                    m_pAccountDelegate->chooseRegionBack(false, NULL);
                }
                    break;
                    
                case ID_CONNECTION_LOST:
				{
					m_pAccountDelegate->accountServerLost();
				}
                    break;

				
                default:
				{
					m_pAccountDelegate->otherAccountMsg(pPacket->data[1]);
				}
                    break;
			}
		}
            break;
            
        default:
            //m_pAccountDelegate->otherReceiveMsg(pPacket->data[0]);
            break;
	}
    
	m_pAccountServer->RemoveTopPacket();
}

//---------------------------------------------------------------------------------------------------------------------------/
void CServerHelper::_ReceiveGamePacket()
{
    if(NULL == m_pGameDelegate)
    {
        return;
    }
    Packet *pPacket = m_pGameServer->GetTopPacket(); 
    
	if(NULL == pPacket)
	{
		return;
	}
    
	switch (pPacket->data[0])
	{
        case ID_CONNECTION_REQUEST_ACCEPTED:
		{
			// 连接成功
			m_pGameDelegate->connectRegionBack(true);
		}
            break;
            
        case ID_GAME_LOGING:
		{
            // 登陆选区信息
			switch(pPacket->data[1])
			{
                case ID_LOGING_LOGING_SUCCESS:
				{
					// 登陆区域成功
					m_pGameDelegate->loginRegionBack(true);
				}
                    break;
                    
                case ID_LOGING_ERROR:
                {
                    // 登陆区域失败
                    m_pGameDelegate->loginRegionBack(false);
                }
                    break;
                    
                case ID_LOGING_CREATENAME:
				{
					// 获取服务器选区信息
					m_pGameDelegate->regionNoRole();
				}
                    break;

				case ID_LOGING_NAME_REPEAT:
					{
						m_pGameDelegate->createNameRepeat();
					}
					break;

				case ID_LOGING_MESSAGE:
					{
						RakNet::BitStream bsReceive(pPacket->data, pPacket->length, false);
						bsReceive.IgnoreBytes(2);
						char Name[32] = {0};
						char text[256] = {0};
						int lenth = 0;

						while(1)
						{
							if(!bsReceive.Read(Name, 32))
							{
								break;
							}
							bsReceive.Read(lenth);
							bsReceive.Read(text, lenth);
							m_pGameDelegate->recvChatFromName(Name, text, lenth);
						}
						
					}
					break;
            }
            break;
        }
        case ID_GAME_ROOMING:
        {
            // 房间相关信息
            switch (pPacket->data[1]) 
            {
                case ID_ROOM_ANFIGHT:
                {
                    // 开始战斗
                    
                    anFight p;
                    RakNet::BitStream bsReceive(pPacket->data, pPacket->length, false);
					bsReceive.IgnoreBytes(2);
					int id;
                    bsReceive.Read((char *)&p, sizeof(p));  
                    
                    m_pGameDelegate->startFightBack(true, p);
                }
                    break;

				case ID_ROOM_MESSAGE_SUCCESS:
					{
						RakNet::BitStream bsReceive(pPacket->data, pPacket->length, false);
						bsReceive.IgnoreBytes(2);
						int id;
						bsReceive.Read(id);
						char szRecv[512];
						bsReceive.Read(szRecv, pPacket->length-6);  

						m_pFightDelegate->roomChat(id, szRecv, pPacket->length-6);
					}
					break;
					
                    
                case ID_ROOM_FIGHT:
                {
                    if(NULL == m_pFightDelegate)
                    {
                        return;
                    }
                    
                    switch(pPacket->data[2])
                    {
						
                        case ID_FIGHT_MOVE_SUCCESS:
                        {
                            Move movePacket;
                            
                            RakNet::BitStream bsReceive(pPacket->data, pPacket->length, false);
                            bsReceive.IgnoreBytes(3);
							int id;
							bsReceive.Read(id);
                            bsReceive.Read((char *)&movePacket, sizeof(movePacket));  
                            
                            m_pFightDelegate->enemyMove(id, movePacket);
                        }
                            break;
                            
                        case ID_FIGHT_ATTACT_SUCCESS:
                        {
                            AttactRecv attackPacket;
                            
                            RakNet::BitStream bsReceive(pPacket->data, pPacket->length, false);
                            bsReceive.IgnoreBytes(3);
							int id;
							bsReceive.Read(id);
                            bsReceive.Read((char *)&attackPacket, sizeof(attackPacket));  
                            
							
                            m_pFightDelegate->attackSuccess(id, attackPacket);
                        }
                            break;

					/*
                        case ID_FIGHT_ATTACT_ENEMY:
                        {
                            AttactRecv attackPacket;
                            
                            RakNet::BitStream bsReceive(pPacket->data, pPacket->length, false);
                            bsReceive.IgnoreBytes(3);
                            bsReceive.Read((char *)&attackPacket, sizeof(attackPacket));  
                            
                            m_pFightDelegate->enemyAttack(attackPacket);
                        }
                            break;
							*/
							
                        default:
                            break;
                    }
                    
                                       
                }
                    break;
                    
                case ID_ROOM_USER_QUIT:
                {
                    m_pGameDelegate->userLost();
                }
                    break;
                    
                default:
                    break;
            }
        }
            break;
        case ID_CONNECTION_LOST:
        {
            m_pGameDelegate->gameServerLost();
        }
            break;
        default:
            break;
	}
    
	m_pGameServer->RemoveTopPacket();
}

